package com.suning.sawp.web.controller;

import java.lang.reflect.Type;
import java.security.Principal;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.constants.LoggerConstants;
import com.suning.sawp.intf.store.CallRecordsService;
import com.suning.sawp.po.store.CallRecords;
import com.suning.sawp.po.store.CallRecords.CALLTYPE;
import com.suning.sawp.service.util.AESUtils;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.web.exception.MobileException;
import com.suning.sawp.web.exception.MyGsonView;

/**
 * 店员拨打电话记录接口
 * @author 15050519
 *
 */
@Controller
@RequestMapping("/callrecords")
public class CallRecordsController extends DjBaseController{

    private static final Logger LOGGER = LoggerFactory
            .getLogger(LoggerConstants.SAWP_SERVICE);
    
    private static final Gson json = new GsonBuilder().setDateFormat(DateUtils.DEFAULT_TIME_PATTERN).create();
    
    @Resource
    CallRecordsService callRecordsService;
    
    /**
     * 保存拨打电话记录
     * @param principal
     * @param telNo
     * @param callTime
     * @param callType
     * @return
     * @throws MobileException
     */
    @RequestMapping("/save.do")
    public MyGsonView save(Principal principal, 
            @RequestParam(value = "custNo", required = false) String custNo, 
            @RequestParam(value = "telNo", required = false) String telNo, 
            @RequestParam(value = "callTime", required = false) String callTime, 
            @RequestParam(value = "callType", required = false) Integer callType) throws MobileException {
        Object[] args = {custNo, telNo, callTime, callType, principal.getName()};
        LOGGER.debug("callrecords/save.do params:custNo={}, telNo={}, callTime={}, callType={}, staffId={}",
                args);
        //设置返回对象
        MyGsonView view = createGsonView();
        
        //记录对象
        CallRecords record = new CallRecords();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.DEFAULT_TIME_PATTERN);
            //呼叫时间转换
            record.setCallTime(sdf.parse(callTime));
        } catch (Exception e) {
            LOGGER.error("CallRecords.callTime转换异常,", e);
            MessageFormat form = new MessageFormat(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0004));
            throw new MobileException(ErrorCodeConstants.ERR_0004, form.format(new String[]{"callTime"}));
        }
        record.setCustNo(custNo);
        record.setTelNo(telNo);
        record.setStaffId(principal.getName());
        record.setCallType(callType);
        //参数校验
        checkParamers(record);
        
        try {
            //保存操作
            boolean sucflg = callRecordsService.save(record);
            //保存失败
            if (!sucflg) {
                LOGGER.error("保存CallRecords失败, {}", sucflg);
                setErrorMsg(view, ErrorCodeConstants.ERR_0005);
            }
        } catch (Exception e) {
            LOGGER.error("保存CallRecords失败, ", e);
            setErrorMsg(view, ErrorCodeConstants.ERR_0002);
        }

        return view;
    }
    
    /**
     * 批量保存呼叫记录
     * @param principal
     * @param callRecords
     * @return
     * @throws MobileException
     */
    @RequestMapping("/batchSave.do")
    public MyGsonView save(Principal principal, 
            @RequestParam(value = "callRecords", required = false) String callRecords) throws MobileException {
        LOGGER.debug("callrecords/batchSave.do, callRecords : {}, staffId:{}", callRecords, principal.getName());
        //设置返回对象
        MyGsonView view = createGsonView();
        //参数判空处理
        if (StringUtils.isBlank(callRecords)) {
            LOGGER.error("参数callRecords必填");
            setErrorMsg(view, ErrorCodeConstants.ERR_0003);
        } else {
            List<CallRecords> list = null;
            try {
                Type type = new TypeToken<List<CallRecords>>() {
                }.getType();
                list = json.fromJson(callRecords, type);
            } catch (JsonSyntaxException e) {
                LOGGER.error("batchSave 处理失败", e);
                MessageFormat form = new MessageFormat(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0004));
                throw new MobileException(ErrorCodeConstants.ERR_0004, form.format(new String[]{"callRecords"}));
            }
            //校验参数合法性
            checkParamers(list, principal.getName());
            try { 
                boolean sucFlg = callRecordsService.batchSave(list);
                if (!sucFlg) {
                    LOGGER.error("保存CallRecords失败, {}", sucFlg);
                    setErrorMsg(view, ErrorCodeConstants.ERR_0005);
                }
            } catch (Exception e) {
                LOGGER.error("batchSave 处理失败", e);
                setErrorMsg(view, ErrorCodeConstants.ERR_0002);
            }
        }
        
        return view;
    }
    
    /**
     * 参数校验
     * @param list
     * @param staffId
     * @throws MobileException
     */
    private void checkParamers (List<CallRecords> list, String staffId) throws MobileException {
        if (CollectionUtils.isEmpty(list)) {
            LOGGER.error("参数callRecords数组为空");
            MessageFormat form = new MessageFormat(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0004));
            throw new MobileException(ErrorCodeConstants.ERR_0004, form.format(new String[]{"callRecords"}));
        } else {
            for (CallRecords record : list) {
                if (null != record) {
                    record.setStaffId(staffId);
                }
                checkParamers(record);
            }
        }
    }
    
    /**
     * 参数校验
     * @param record
     * @throws MobileException
     */
    private void checkParamers (CallRecords record) throws MobileException {
        //参数判空处理
        if (null == record || StringUtils.isBlank(record.getCustNo())) {
            LOGGER.error("参数为空");
            paramInvalid(ErrorCodeConstants.ERR_0003, "custNo");
        } else if (StringUtils.isBlank(record.getTelNo())) {
            LOGGER.error("参数telNo必填");
            paramInvalid(ErrorCodeConstants.ERR_0003, "telNo");
        } else if (null == record.getCallType()) {
            LOGGER.error("参数callType必填");
            paramInvalid(ErrorCodeConstants.ERR_0003, "callType");
        } 
        //解密客户编码
        String custNum = AESUtils.decrypt(record.getCustNo(), ConfigConstants.AES_KEY);
        //解密失败,抛异常
        if (StringUtils.isBlank(custNum)) {
            LOGGER.error("CallRecords.custNo解密异常,");
            paramInvalid(ErrorCodeConstants.ERR_0004, "custNo");
        }
        record.setCustNo(custNum);
        //解密手机号
        String phoneNum = AESUtils.decrypt(record.getTelNo(), ConfigConstants.AES_KEY);
        //解密失败,抛异常
        if (StringUtils.isBlank(phoneNum)) {
            LOGGER.error("CallRecords.telNo解密异常,");
            paramInvalid(ErrorCodeConstants.ERR_0004, "telNo");
        }
        //顾客手机号
        record.setTelNo(phoneNum);
        
        //校验呼叫时间
        if (null == record.getCallTime()) {
            LOGGER.error("CallRecords.callTime转换异常,");
            paramInvalid(ErrorCodeConstants.ERR_0004, "callTime");
        }
        
        record.setCreateTime(new Date());
        
        //呼叫类型1,2判断
        if (CALLTYPE.CALL_IN.getValue() != record.getCallType().intValue()
                && CALLTYPE.CALL_OUT.getValue() != record.getCallType().intValue()) {
            LOGGER.error("CallRecords.callType不合法");
            paramInvalid(ErrorCodeConstants.ERR_0004, "callType");
        }
    }
    
    /**
     * 错误信息封装
     * @param errorCode
     * @param paramName
     * @throws MobileException
     */
    private void paramInvalid(String errorCode, String paramName) throws MobileException {
        MessageFormat form = new MessageFormat(ErrorCodeConstants.ERR_MAP.get(errorCode));
        throw new MobileException(errorCode, form.format(new String[]{paramName}));
    }
}
